package com.ruoyi.HKISAPI.demo.function.basic.guard;


import com.ruoyi.HKISAPI.demo.entity.DeviceInfoDTO;
import com.ruoyi.HKISAPI.demo.entity.DeviceLinkStatusDTO;
import com.ruoyi.HKISAPI.demo.function.basic.AlarmGuardDemo;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.nio.client.methods.HttpAsyncMethods;

import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future;

/**
 * @author zhengxiaohui
 * @date 2024/1/10 10:43
 * @desc 长链接线程
 */
public class LongLinkThread implements Runnable {

    private DeviceInfoDTO deviceInfo;
    private String url;
    private CloseableHttpAsyncClient closeableHttpAsyncClient;

    private CopyOnWriteArrayList<Character> chBuffer = new CopyOnWriteArrayList<>();


    public LongLinkThread(DeviceInfoDTO deviceInfo) {
        this.deviceInfo = deviceInfo;
        this.url = (deviceInfo.getHttpType() == 0 ? "http://" : "https://")
                + deviceInfo.getDevIp()
                + ":"
                + deviceInfo.getDevPort()
                + "/ISAPI/Event/notification/alertStream";
    }

    @Override
    public void run() {
        // 初始化http长链接，设置摘要认证信息
        httpAysncInit(deviceInfo.getUsername(), deviceInfo.getPassword());

        longLink();
    }

    private void httpAysncInit(String user, String password) {
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, password));
        closeableHttpAsyncClient = HttpAsyncClients.custom().setDefaultCredentialsProvider(credentialsProvider).build();
    }

    private void longLink() {
        DeviceLinkStatusDTO deviceLongLinkStatus = AlarmGuardDemo.devLinkStatusMap.get(this.deviceInfo);
        deviceLongLinkStatus.stopLink.set(false);
        AlarmGuardDemo.devLinkStatusMap.put(this.deviceInfo, deviceLongLinkStatus);

        chBuffer.clear();
        try {
            // 建立回调功能
            FutureCallback<Boolean> callback = new FutureCallback<Boolean>() {
                public void cancelled() {
                    // TODO Auto-generated method stub
                    System.out.println("cancelled");
                }

                public void completed(Boolean arg0) {
                    // TODO Auto-generated method stub
                    System.out.println("completed");
                }

                public void failed(Exception arg0) {
                    // TODO Auto-generated method stub
                    System.out.println("failed");
                }
            };
            // 打开连接
            closeableHttpAsyncClient.start();
            // 重新连接查询线程并且设置超时
            ReConnect recn = new ReConnect(closeableHttpAsyncClient, deviceInfo, chBuffer);
            // 在新的线程中执行recn对象的run()方法，实现多线程并发执行的效果
            Thread rethread = new Thread(recn);
            rethread.start();

            // 连接
            Future<Boolean> future = closeableHttpAsyncClient.execute(
                    HttpAsyncMethods.createGet(url),
                    new ResponseConsumer(closeableHttpAsyncClient, deviceInfo, chBuffer),
                    callback);
            Boolean result = future.get();
            if (result != null && result) {
                System.out.println("Request successfully executed");
            } else {
                System.out.println("Request failed");
            }
            System.out.println("Shutting down");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return;
    }


}
